package fetch.nokiasportstracker;

import java.io.BufferedReader;
import java.io.FileReader;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class KMLParser extends DefaultHandler {
	
	public String tempVal;
	public StringBuffer tempBuff;
	public int countPlacemark;
	public int id;
	public String user;
	public String activity;
	public String time;
	public String day;
	public String month;
	public String year;
	public String duration;
	public String distance;
	public String speed_avg;
	public String speed_max;
	public String pace_avg;
	public String pace_max;
	public String coordinates;
	
	public KMLParser(){
		
	}
	
	public String parse(String kml_filename) throws Exception{
		
		id = Integer.parseInt(kml_filename.substring(kml_filename.indexOf("/")+1,kml_filename.length()-4));
	    countPlacemark = 0;
	    coordinates = "";
	    
	    BufferedReader in = new BufferedReader(new FileReader(kml_filename));
	    //get a factory
	    SAXParserFactory spf = SAXParserFactory.newInstance();
	    //get a new instance of parser
	    SAXParser sp = spf.newSAXParser();
	    //parse the file and also register this class for call backs
        sp.parse(new InputSource(in),this);
        
        return "INSERT INTO data VALUES("+id+",'"+user+"','"+activity+"','"+time+"','"+day+"','"+month+"','"+year+"','"+duration+"','"+distance+"','"+speed_avg+"','"+speed_max+"','"+pace_avg+"','"+pace_max+"',GeomFromText('MULTIPOINT("+coordinates.substring(0,coordinates.length()-1)+")'),Envelope(GeomFromText('MULTIPOINT("+coordinates.substring(0,coordinates.length()-1)+")')));";
	}
	
	//all elements are inside the first Placemark
	
	 //Event Handlers
	 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		 //reset
		 tempVal = "";
		 tempBuff = null;
		 
		 if(qName.equals("Placemark"))
			 countPlacemark++;
    }
	 
	 public void characters(char[] ch, int start, int length) throws SAXException {
		 tempVal = new String(ch,start,length);
		 if(tempBuff == null)
			 tempBuff = new StringBuffer(tempVal);
		 else
		     tempBuff = tempBuff.append(tempVal);
	 }
	 
	 public void endElement(String uri, String localName, String qName) throws SAXException {
		 try{
			 if(qName.equalsIgnoreCase("description") && countPlacemark <= 1)
				 parseDescription(tempBuff.toString());
		     if(qName.equals("coordinates") && countPlacemark <= 1)
			     parseCoordinates(tempBuff.toString());
		 }catch(Exception e){
			 //System.out.println(e);
			// e.printStackTrace();
		 }

	 }
	 
	 
	 public void parseDescription(String desc) throws Exception{
		 StringTokenizer st = new StringTokenizer(desc, "\n");
		 while(st.hasMoreTokens()){
			 String token = st.nextToken().trim();
			 if(token.contains("User"))
				 this.user = extractValue(token);
			 
			 if(token.contains("Activity"))
				 this.activity = extractValue(token);
			 
			 if(token.contains("Start time")){
				 /*
				  * 12.04.10 11:28
				  */
				 String value = extractValue(token);
				 String [] timesplit = value.split(" ");
				 String [] datesplit = timesplit[0].split("\\.");
				 SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yy HH:mm",Locale.ITALY);
				 Calendar cal = new GregorianCalendar();
				 cal.setTime(formatter.parse(value));
				 
				 //System.out.println("----------"+cal.getTime());
				 
				 
				 this.year = Integer.toString(cal.get(Calendar.YEAR));
				 this.month = Integer.toString(cal.get(Calendar.MONTH));
				 this.day = Integer.toString(cal.get(Calendar.DAY_OF_MONTH));
				 this.time = Integer.toString(cal.get(Calendar.HOUR))+":"+Integer.toString(cal.get(Calendar.MINUTE));				
				 //this.day = datesplit[0];
				 //this.month = datesplit[1];
				 //this.year = datesplit[2];
				 this.time = timesplit[1];
			 }
			 if(token.contains("Duration"))
				 this.duration = extractValue(token);
			 
			 if(token.contains("Distance"))
				 this.distance = extractValue(token);
			
			 if(token.contains("Speed avg"))
				 this.speed_avg = extractValue(token);
			 
			 if(token.contains("Speed max"))
				 this.speed_max = extractValue(token);
			 
			 if(token.contains("Pace avg"))
				 this.pace_avg = extractValue(token);
			 
			 if(token.contains("Pace max"))
				 this.pace_max = extractValue(token);
			 
		 }
		 
	 }
	 
	 public void parseCoordinates(String coord) throws Exception{		 
		 StringTokenizer st = new StringTokenizer(coord, "\n");
		 StringBuffer sb = new StringBuffer();
		 while(st.hasMoreTokens()){
			 String token = st.nextToken();
			 String [] split = token.split(",");
			 double lon = Double.parseDouble(split[0]);
			 double lat = Double.parseDouble(split[1]);
			
			 BigDecimal bd = new BigDecimal(lon, new MathContext(6));
			 lon = bd.doubleValue();
			 bd = new BigDecimal(lat, new MathContext(6));
			 lat = bd.doubleValue();
			 sb.append(Double.toString(lon)+" "+Double.toString(lat)+",");
		 }
			 
		 coordinates = sb.toString();

	 }
	 
	 
	 
	 public String extractValue(String token){
		 /*
		  *  example:
		  *  <tr><td>User</td><td>felendzer</td></tr> 
		  */
		 String [] pieces = token.split("</td>");
		 
		 return pieces[1].substring(4,pieces[1].length());		 
	 }

}
